using MultiAgentsClient.ChatDataStructures;
using MultiAgentsShared;
using static MultiAgentsClient.Manager.SystematicNotificationManager;
using static MultiAgentsClient.Manager.WorkflowOperator;

namespace MultiAgentsClient.Presentation;

public partial record NotificationsModel
{
    private readonly IEventBus eventBus;

    // notificationId, countDown
    private readonly List<(int Id, System.Timers.Timer Timer)> workflowExecuteCountdowns = [];
    public IListState<WorkflowNotificationDisp> Notifications => ListState<WorkflowNotificationDisp>.Empty(this);

    public NotificationsModel()
    {
        eventBus = EventBus.Instance;

        eventBus.Subscribe<RecieveSystematicNotificationEvent>(async cmd => { await NotificationEvent(cmd); });
    }

    public async Task ExecuteEventWorkflow(int notificationId)
    {
        eventBus.Publish(new ExecuteEventWorkflowCommand(notificationId));
        await OnWorkflowNotificationHandled(notificationId);
    }

    public async Task OnWorkflowNotificationHandled(int notificationId)
    {
        (int Id, System.Timers.Timer Timer) tupleToRemove = workflowExecuteCountdowns.FirstOrDefault(tuple => tuple.Id == notificationId);

        if (tupleToRemove.Timer != null)
        {
            workflowExecuteCountdowns.Remove(tupleToRemove);
            tupleToRemove.Timer.Dispose();
        }

        await Notifications.RemoveAllAsync(match: item => item.Id == notificationId);
        eventBus.Publish(new NotificationProccessedCommand(notificationId));
    }

    private async ValueTask NotificationEvent(RecieveSystematicNotificationEvent cmd)
    {
        foreach (WorkflowNotification notification in cmd.Notifications)
        {
            if (notification.requireApproval)
            {
                await Notifications.AddAsync(notification.ToDisp(null));
            }
            else
            {
                System.Timers.Timer? countdown = new(1000)
                {
                    AutoReset = true
                };
                int seconds = 5;

                countdown.Elapsed += async (sender, e) =>
                {
                    seconds--;
                    await Notifications.UpdateAsync(notification.ToDisp(seconds.ToString()));
                    if (seconds <= 0)
                    {
                        countdown.Stop();
                        await ExecuteEventWorkflow(notification.id);
                    }
                };

                await Notifications.AddAsync(notification.ToDisp(seconds.ToString()));
                countdown.Start();
                workflowExecuteCountdowns.Add((notification.id, countdown));
            }
        }
    }
}
